cc.Class({
    extends: cc.Component,

    properties: {
        scrollView: cc.Node,
        itemsArr: [cc.Node],
        Vertical: false,
        //间距
        gap_x: 0,
        gap_y: 0,
    },
    onLoad() {
    },
    //初始化
    init() {
        this.scrView = this.scrollView.getComponent(cc.ScrollView);
        this.content = this.scrView.content;
        this.height = this.content.height;
        this.width = this.content.width;
        this.node_pools = new Map();
        //存储item的map
        this.item_templates = new Map();
        this.itemsArr.forEach((tpl, index) => {
            tpl.active = false;
            this.item_templates.set(index, tpl);
        });
        this.updateInterval = 0.2;
    },
    //滑动中回调
    update(dt) {
        this.updateTimer += dt;
        if (this.updateTimer < this.updateInterval) {
            return; // we don't need to do the math every frame
        }

        if (!this.items || !this.items.length) {
            return;
        }

        let start = 0;
        let stop = 0;
        //垂直滚动
        if (this.Vertical) {
            let posy = this.content.y;
            if (posy < 0)
                posy = 0;
            if (posy > this.content.height - this.height)
                posy = this.content.height - this.height;

            let viewport_start = -posy;
            let viewport_stop = viewport_start - this.height;

            while(this.items[start].y - this.items[start].height > viewport_start)
                start++;
            stop = start;
            while(this.items[stop] && this.items[stop].y > viewport_stop)
                stop++;
        } else { //水平滚动
            let posx = this.content.x;
            if (posx > 0)
                posx = 0;
            if (posx < this.width - this.content.width)
                posx = this.width - this.content.width;

            let viewport_start = -posx;
            let viewport_stop = viewport_start + this.width;

            while (this.items[start].x + this.items[start].width < viewport_start)
                start++;
            stop = start;
            while (this.items[stop] && this.items[stop].x > viewport_stop)
                stop++;
        }

        if (start != this.start_index || stop != this.stop_index) {
            this.start_index = start;
            this.stop_index = stop;
            this.render_items();
        }
    },

    //生成node
    spawn_node(key) {
        let node;
        let pools = this.node_pools.get(key);
        if (pools && pools.length > 0) {
            node = pools.pop();
        } else {
            node = cc.instantiate(this.item_templates.get(key));
            node.active = true;
        }
        node.parent = this.content;
        return node;
    },
    //回收item
    recycle_item(item) {
        if (item.node && cc.isValid(item.node)) {
            let pools = this.node_pools.get(item.data.key);
            if (!pools) {
                pools = [];
                this.node_pools.set(item.data.key, pools);
            }
            pools.push(item.node);
            item.node.removeFromParent();
            item.node = null;
        }
    },
    //清除items
    clear_items() {
        if (this.items) {
            this.items.forEach((item) => {
                this.recycle_item(item);
            });
        }
    },
    //渲染items
    render_items() {
        let item;
        for(var i = 0,len = this.items.length; i < len; i++)
        {
            item = this.items[i];
            if(!item) return;

            if(i < this.start_index || i > this.stop_index)
            {
                if(item.node) {
                    this.recycle_item(item);
                }
            }
            else{
                if(!item.node) {
                    item.node = this.spawn_node(item.data.key);
                    this.item_setter(item.node, item.data);
                }
                item.node.setPosition(item.x, item.y);
            }
        }
    },
    //赋值item
    pack_item(index, data) {
        var _templates = this.item_templates.get(data.key)
        let item = {
            x: 0,
            y: 0,
            width: _templates.width,
            height: _templates.height,
            data: data,
            node: null,
        };
        return item;
    },
    //item具体赋值
    item_setter(item, data) {
        item.getComponent(cc.Component).itemDataAssignment(data);
        return [item.width, item.height];
    },
    //布局items
    layout_items(start) {
        if (this.items.length <= 0) {
            return;
        }
        let start_pos = 0;
        if (start > 0) {
            let prev_item = this.items[start - 1];
            if (this.Vertical) {
                start_pos = prev_item.y - prev_item.height - this.gap_y;
            } else {
                start_pos = prev_item.x + prev_item.width + this.gap_x;
            }
        }
        for (let index = start, stop = this.items.length; index < stop; index++) {
            let item = this.items[index];
            if (this.Vertical) {
                item.x = 0;
                item.y = start_pos;
                start_pos -= item.height + this.gap_y;
            } else {
                item.y = 0;
                item.x = start_pos;
                start_pos += item.width + this.gap_x;
            }
        }
    },
    //调整content
    resize_content() {
        if (this.items.length <= 0) {
            this.content.width = 0;
            this.content.height = 0;
            return;
        }
        let last_item = this.items[this.items.length - 1];
        if (this.Vertical) {
            this.content.height = Math.max(this.height, last_item.height - last_item.y);
        } else {
            this.content.width = Math.max(this.width, last_item.x + last_item.width);
        }
    },
    //重置渲染开始和结束点
    reset_RenderIndex()
    {
        this.start_index = 0;
        this.stop_index = 0;
    },
    //设置数据
    set_data(datas) {
        this.clear_items();
        this.items = [];
        datas.forEach((data, index) => {
            let item = this.pack_item(index, data);
            this.items.push(item);
        });
        this.layout_items(0);
        this.resize_content();
        this.reset_RenderIndex();
        if (this.Vertical) {
            this.content.y = 0;
        } else {
            this.content.x = 0;
        }
    },
    //插入数据
    insert_data(index, datas) {
        if (datas.length == 0) {
            return;
        }
        if (!this.items) {
            this.items = [];
        }
        if (index < 0 || index > this.items.length) {
            console.log("无效的index", index);
            return;
        }
        let is_append = index == this.items.length;
        let items = [];
        datas.forEach((data, index) => {
            let item = this.pack_item(index, data);
            items.push(item);
        });
        this.items.splice(index, 0, ...items);
        this.update_ItemIndex();
        this.layout_items(index);
        this.resize_content();
        this.reset_RenderIndex();
    },
    //删除数据
    remove_data(index) {
        if(!this.items)
        {
            return;
        }
        if(this.items.length == 0)
        {
            return;
        }
        if (index < 0 || index > this.items.length) {
            console.log("无效的index", index);
            return;
        }
        this.recycle_item(this.items[index]);
        this.items.splice(index, 1);
        this.update_ItemIndex();
        this.layout_items(index);
        this.resize_content();
        this.reset_RenderIndex();
    },
    //更新索引
    update_ItemIndex()
    {
        this.items.forEach((_item, index) => {
            _item.data.index = index;
        });
    },
    //追加数据
    append_data(datas) {
        if (!this.items) {
            this.items = [];
        }
        this.insert_data(this.items.length, datas);
    },
    //滑动到底
    scroll_to_end() {
        if (this.Vertical) {
            this.scrView.getComponent(cc.ScrollView).scrollToBottom(2);
        } else {
            this.scrView.getComponent(cc.ScrollView).scrollToRight(2);
        }
    },
    //销毁
    destroy_items() {
        this.clear_items();
        this.node_pools.forEach((pools, key) => {
            pools.forEach((node) => {
                node.destroy();
            });
        });
        this.node_pools = null;
        this.items = null;
    },
    //获取对象
    get_Item(index){
        if(index >= 0 && index < this.items.length)
        {
            return this.items[index];
        }
    },
    //刷新当前视界
    Refresh_viewPort()
    {
        let item;
        for (let i = this.start_index; i <= this.stop_index + 1; i++) {
            if (!this.items[i]) {
                return
            }
            item = this.items[i];
            if (item.node) {
                this.item_setter(item.node, item.data);
            }
        }
    },

});